package com.achievo.reportserver.config;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;

import org.apache.log4j.Logger;


/**
 * 
 * Report Server
 * write at Jan 21, 2010
 * @author <a href="mailto:chinaoryx@gmail.com">Hyman.Zhang (Zhang Haipeng)</a>
 * @version 1.0
 * 
 *
 */
public class ReportConfigStore {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(ReportConfigStore.class);
	
	private static final Map<String, ReportRoot> fileMap = new Hashtable<String, ReportRoot>();
	
	private static final Map<String, ReportDef> reportMap = new Hashtable<String, ReportDef>();
	
	
	public static synchronized Collection<ReportDef> getReportList(String groupId){
		return reportMap.values();
	}
	
	public static synchronized ReportDef getReport(String reportId){
		return reportMap.get(reportId);
	}
	
	
	
	public static synchronized void onDeleteFile(String fileName){
		fileMap.remove(fileName);		
		refreshStore();
	}
	
	
	
	
	
	
	public static synchronized void onNewUpdateFile(String fileName, ReportRoot reportRoot){		
		fileMap.put(fileName, reportRoot);
		refreshStore();		
	}
	
	
	public static  void refreshStore(){
		
		Set<Entry<String, ReportRoot>> entrySet = fileMap.entrySet();
		
		reportMap.clear();
		
		for (Entry<String, ReportRoot> entry : entrySet) {
			String fileName = entry.getKey();
			ReportRoot reportRoot = entry.getValue();
			List<ReportDef> reportDefList = reportRoot.getReportList();
			if (reportDefList == null) {
				continue;
			}
			for (ReportDef reportDef : reportDefList) {
				String reportId = reportDef.getReportId();
				reportDef.setFromConfigFile(fileName);
				if (reportMap.containsKey(reportId)) {
					logger.error("duplicated reportId(" + reportId + ")!!");
					continue;
				}
				
				
				// override the param List				
				String reportTemplateRoot = ConfigFactory.getServerConfig().getString("reportTemplateRoot");
				String reportFile = reportDef.getReportTemplateFile();
				String fileLoc = reportTemplateRoot + File.separator + reportFile;				
				try {
					URL url = ReportConfigStore.class.getClassLoader().getResource(fileLoc);
					JasperReport jasperReport = (JasperReport) JRLoader.loadObject(url);
					JRParameter[] jrParamList = jasperReport.getParameters();
					List<ReportParam> paramList = new ArrayList<ReportParam>();
					for (JRParameter jrParameter : jrParamList) {
						String name = jrParameter.getName();
						String type = jrParameter.getValueClassName();						
						if (jrParameter.isSystemDefined()){
							continue;
						}
						ReportParam param = new ReportParam();
						param.setParamName(name);
						param.setParamType(type);	
						paramList.add(param);
					}
					reportDef.setParamList(paramList);
					logger.info("report("+reportId+") param override ok!");
				} catch (JRException e) {
					logger.error("report("+reportId+") param override error!", e);
				}
				
				reportMap.put(reportId, reportDef);
				
			}
		}
		
	}
	
	public static void main(String[] args) {		
	}
	

}
